package com.xai.pg.service;

import com.xai.pg.util.Conf;
import com.xai.pg.util.FileUtil;
import com.xai.pg.util.VMUtil;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * @author Kxvz
 */
@Service
public class PublicGeneratorService {

    private String javaBaseDir;
    private String basePath;


    /**
     * <p>
     * 通用部分公共生成器</p>
     */
    public void generator() {
        Logger.getLogger(PublicGeneratorService.class.getName()).log(Level.INFO, "==== PublicGeneratorService Generator ===================================================");
        this.init();
        this.generatorDir();
        this.generatePom();
        this.generateBanner();
        this.generatorApplication();
        this.generatorJsonUtil();
        this.generatorConfigFiles();
        this.generatorGeneralData();
        this.generatorLauncher();
    }

    /**
     * 初始化项目的根目录
     */
    private void init() {
        this.basePath = Conf.getBasePath();
        this.javaBaseDir = Conf.getJavaBasePath();
    }

    /**
     * 生成项目的目录结构
     */
    private void generatorDir() {
        String basePackage = Conf.getGroup();
        String javaFilePath = basePackage.replace(".", "/");
        javaBaseDir = basePath + "/src/main/java/" + javaFilePath;

        FileUtil.createDir(basePath);
        FileUtil.createDir(basePath + "/src/main/java");
        FileUtil.createDir(basePath + "/src/main/resources");
        FileUtil.createDir(basePath + "/src/test/java");
        FileUtil.createDir(javaBaseDir);
        FileUtil.createDir(javaBaseDir + "/data/entity");
        FileUtil.createDir(javaBaseDir + "/data/data");
        FileUtil.createDir(javaBaseDir + "/service/dao");
        FileUtil.createDir(javaBaseDir + "/gateway");
        FileUtil.createDir(javaBaseDir + "/config");
        FileUtil.createDir(javaBaseDir + "/constant");
        FileUtil.createDir(javaBaseDir + "/exception");
        FileUtil.createDir(javaBaseDir + "/config/interceptor");
    }

    private void generatorGeneralData() {
        String group = Conf.getGroup();
        Map<String, Object> obj = new HashMap<>(3);
        obj.put("group", group);

        String str = VMUtil.toStr(obj, "vm/general/java/base.vm");
        FileUtil.createFile(javaBaseDir + "/data/Base.java");
        FileUtil.writeToFile(javaBaseDir + "/data/Base.java", str);

        String pageDataStr = VMUtil.toStr(obj, "vm/general/java/PageData.vm");
        FileUtil.createFile(javaBaseDir + "/data/PageData.java");
        FileUtil.writeToFile(javaBaseDir + "/data/PageData.java", pageDataStr);

        String requestDataStr = VMUtil.toStr(obj, "vm/general/java/RequestData.vm");
        FileUtil.createFile(javaBaseDir + "/data/RequestData.java");
        FileUtil.writeToFile(javaBaseDir + "/data/RequestData.java", requestDataStr);

        String responseDataStr = VMUtil.toStr(obj, "vm/general/java/ResponseData.vm");
        FileUtil.createFile(javaBaseDir + "/data/ResponseData.java");
        FileUtil.writeToFile(javaBaseDir + "/data/ResponseData.java", responseDataStr);

        String codeStr = VMUtil.toStr(obj, "vm/general/java/Code.vm");
        FileUtil.createFile(javaBaseDir + "/constant/Code.java");
        FileUtil.writeToFile(javaBaseDir + "/constant/Code.java", codeStr);

        String absControlStr = VMUtil.toStr(obj, "vm/general/java/AbsController.vm");
        FileUtil.createFile(javaBaseDir + "/gateway/AbsController.java");
        FileUtil.writeToFile(javaBaseDir + "/gateway/AbsController.java", absControlStr);
    }

    /**
     * 生成各种配置类:<br/>
     * 通用Exception<br/>
     * Swagger文档配置<br/>
     * 请求频率限制<br/>
     */
    private void generatorConfigFiles() {
        String group = Conf.getGroup();

        Map<String, Object> obj = new HashMap<>(3);
        obj.put("group", group);

        String exceptionStr = VMUtil.toStr(obj, "vm/general/java/exception.vm");
        FileUtil.createFile(javaBaseDir + "/exception/CusException.java");
        FileUtil.writeToFile(javaBaseDir + "/exception/CusException.java", exceptionStr);

        String exceptionConfigurerStr = VMUtil.toStr(obj, "vm/general/java/ExceptionConfigurer.vm");
        FileUtil.createFile(javaBaseDir + "/config/ExceptionConfigurer.java");
        FileUtil.writeToFile(javaBaseDir + "/config/ExceptionConfigurer.java", exceptionConfigurerStr);

        String swaggerConfigurationStr = VMUtil.toStr(obj, "vm/general/java/SwaggerConfiguration.vm");
        FileUtil.createFile(javaBaseDir + "/config/SwaggerConfiguration.java");
        FileUtil.writeToFile(javaBaseDir + "/config/SwaggerConfiguration.java", swaggerConfigurationStr);

        String limitInterceptorStr = VMUtil.toStr(obj, "vm/general/java/RequestLimitInterceptor.vm");
        FileUtil.createFile(javaBaseDir + "/config/interceptor/RequestLimitInterceptor.java");
        FileUtil.writeToFile(javaBaseDir + "/config/interceptor/RequestLimitInterceptor.java", limitInterceptorStr);

        String crossInterceptor = VMUtil.toStr(obj, "vm/general/java/WebCrossInterceptor.vm");
        FileUtil.createFile(javaBaseDir + "/config/interceptor/WebCrossInterceptor.java");
        FileUtil.writeToFile(javaBaseDir + "/config/interceptor/WebCrossInterceptor.java", crossInterceptor);

        String sessionListenerStr = VMUtil.toStr(obj, "vm/general/java/SessionListener.vm");
        FileUtil.createFile(javaBaseDir + "/config/SessionListener.java");
        FileUtil.writeToFile(javaBaseDir + "/config/SessionListener.java", sessionListenerStr);

        String webConfigurationStr = VMUtil.toStr(obj, "vm/general/java/WebConfiguration.vm");
        FileUtil.createFile(javaBaseDir + "/config/WebConfiguration.java");
        FileUtil.writeToFile(javaBaseDir + "/config/WebConfiguration.java", webConfigurationStr);
    }

    /**
     * 生成JSON工具类
     */
    private void generatorJsonUtil() {
        String filePath = javaBaseDir + "/util/JsonUtil.java";
        String group = Conf.getGroup();
        Map<String, Object> obj = new HashMap<>();
        obj.put("group", group);
        String str = VMUtil.toStr(obj, "vm/general/java/JsonUtil.vm");
        FileUtil.createFile(filePath);
        FileUtil.writeToFile(filePath, str);
    }

    /**
     * 生成启动类
     */
    private void generatorLauncher() {
        String filePath = javaBaseDir + "/Launcher.java";
        String group = Conf.getGroup();
        Map<String, Object> obj = new HashMap<>(3);
        obj.put("group", group);
        String str = VMUtil.toStr(obj, "vm/general/launcher.vm");
        FileUtil.createFile(filePath);
        FileUtil.writeToFile(filePath, str);
    }

    /**
     * 生成Spring配置文件
     */
    private void generatorApplication() {
        String filePath = basePath + "/src/main/resources/application.yml";
        String name = Conf.get("pro.name");
        Map<String, Object> obj = new HashMap<>(10);
        obj.put("name", name);
        String str = VMUtil.toStr(obj, "vm/general/application.vm");
        FileUtil.createFile(filePath);
        FileUtil.writeToFile(filePath, str);

        String filePathDev = basePath + "/src/main/resources/application-dev.yml";
        obj.put("url", Conf.getDBUrl());
        obj.put("user", Conf.getDBUser());
        obj.put("password", Conf.getDBPass());
        obj.put("group", Conf.getGroup());
        String strDev = VMUtil.toStr(obj, "vm/general/application-dev.vm");
        FileUtil.createFile(filePathDev);
        FileUtil.writeToFile(filePathDev, strDev);
    }

    /**
     * 生成POM文件
     */
    private void generatePom() {
        String filePath = basePath + "/pom.xml";
        String name = Conf.get("pro.name");

        Map<String, Object> obj = new HashMap<>(5);
        obj.put("group", Conf.getGroup());
        obj.put("artifact", name);
        obj.put("name", name);
        String str = VMUtil.toStr(obj, "vm/general/pom.vm");
        FileUtil.createFile(filePath);
        FileUtil.writeToFile(filePath, str);
    }

    /**
     * 生成Banner文件
     */
    private void generateBanner() {
        String filePath = basePath + "/src/main/resources/banner.txt";
        String name = Conf.get("pro.name");

        Map<String, Object> obj = new HashMap<>(3);
        obj.put("name", name);
        String str = VMUtil.toStr(obj, "vm/general/banner.vm");
        FileUtil.createFile(filePath);
        FileUtil.writeToFile(filePath, str);
    }
}
